//
//  JackWebImageManager.m
//  JackToolsBox
//
//  Created by Jack Xue on 2019/12/3.
//  Copyright © 2019 Jack Xue. All rights reserved.
//

#import "JackWebImageManager.h"
#import "JackImageCacher.h"             //负责管理缓存
#import "JKImageDownloadManager.h"      //管理下载
#import<CommonCrypto/CommonDigest.h>    //md5加密


@interface JackWebImageManager(){
    JackImageCacher *_imageCacher;
    JKImageDownloadManager *_downloadManager;
    NSMutableDictionary *_taskDict;     //记录imageView发起的最后一次任务
}
@end

@implementation JackWebImageManager
/*
 1.单例设计的具体实现再看视频
 */
+(JackWebImageManager*)sharedManager{
    static JackWebImageManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (!manager) {
            manager = [[super alloc]init];
        }
    });
    return manager;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        NSLog(@"manager init");
        _imageCacher = [JackImageCacher new];
        _downloadManager = [JKImageDownloadManager new];
        _taskDict = [NSMutableDictionary dictionaryWithCapacity:10];
    }
    return self;
}

#pragma mark - manager查询缓存/下载图片
-(void)sendImgeViewToManager:(UIImageView*)imageView url:(NSString*)url completion:(void(^)(NSError  * _Nullable err))completion{
    //将图片名进行md5处理
    NSString *newKey = [self hashKey:url];
    //1.查找缓存，这个过程不涉及到异步操作可以直接返回
    UIImage *readImage = [_imageCacher checkImageCacheWithKey:newKey];
    if (readImage) {
        /*
         如果缓存能够找到直接使用缓存图片
         此时UIImage已经缓存到内存中，对imageView.image进行赋值内存增加，所有图片完成加载后内存突然增加
         */
        [imageView setImage:readImage];
        return;
    }
    
    //加入下载任务
    NSString *holderKey = [NSString stringWithFormat:@"%p",imageView];
    [self manageDownloaingLine:holderKey task:url];
    [_downloadManager sendDownloadTask:url imageView:holderKey withImage:^(UIImage * _Nullable image) {
        //下载成功
        if ([self checkIsLastTask:holderKey task:url]) {
            dispatch_async(dispatch_get_main_queue(), ^{
                imageView.image = image;
            });
        }
        [self->_imageCacher addImageToCacheWithKey:newKey image:image];
    }fail:^(NSError * _Nonnull err) {
        //下载失败
        if (completion && err) {
            completion(err);
        }
    }];
        
}

#pragma mark - manager清除缓存
-(void)removeAllImageCache{
    [_imageCacher removeAllImageFromCache];
}

#pragma mark - 任务管理应对tableViewCell重用机制产生的错误
-(void)manageDownloaingLine:(NSString*)holder task:(NSString*)taskId{
    [_taskDict setValue:taskId forKey:holder];
}

-(BOOL)checkIsLastTask:(NSString*)holder task:(NSString*)task{
    NSString *lastTask = [_taskDict valueForKey:holder];
    if ([task isEqualToString:lastTask]) {
        //是最后发起的任务
        return YES;
    }else{
        return NO;
    }
}

#pragma mark - key -> hash_name
-(NSString*)hashKey:(NSString*)key{
    const char *cString = [key UTF8String];
    unsigned char digest[CC_MD5_DIGEST_LENGTH];
    CC_MD5(cString, (CC_LONG)strlen(cString), digest);
    
    NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for (NSInteger i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [output appendFormat:@"%02x",digest[i]];
    }
    NSString *result = [NSString stringWithString:output];
    return result;
}
@end
